package com.asia5b.a5mall.middleware.logic.viewmodel.member

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import androidx.lifecycle.MutableLiveData
import com.asia5b.a5mall.middleware.api.CustomThrowable
import com.asia5b.a5mall.middleware.base.SimpleActivity
import com.asia5b.a5mall.middleware.base.SimpleNetParams
import com.asia5b.a5mall.middleware.base.SimpleViewModel
import com.asia5b.a5mall.middleware.config.UserRepository
import com.asia5b.a5mall.middleware.model.bean.CheckSmsBean
import com.asia5b.a5mall.middleware.model.bean.CheckSmsType
import com.asia5b.a5mall.middleware.model.bean.ImageCodeType
import com.asia5b.a5mall.middleware.utils.JsonUtil
import com.asia5b.a5mall.middleware.utils.MD5Util
import com.asia5b.a5mall.middleware.utils.UUID
import com.asia5b.a5mall.middleware.utils.showMessage
import com.google.gson.reflect.TypeToken
import io.reactivex.Observable
import io.reactivex.functions.Consumer
import okhttp3.ResponseBody

/**
 * Created by zhangyuncai on 2020/8/25.
 */
open class AccoutVM : SimpleViewModel() {
    val testLiveData=MutableLiveData<Int>()
    lateinit var checkSmsBean: CheckSmsBean

    fun cloneCheckSmsBean(): CheckSmsBean {
        val anyToJson = JsonUtil.anyToJson(checkSmsBean)
        val type = object : TypeToken<CheckSmsBean>() {}.type
        val newBean = JsonUtil.jsonToAny<CheckSmsBean>(anyToJson, type)!!
        return newBean
    }

    val loadImageCodeLiveData = MutableLiveData<Bitmap>()


    /**
     * @Note   加载Vcode
     * @param  type 类型
     */
    fun loadImageCode(bean: CheckSmsBean) {

        var type = ImageCodeType.LOGIN
        when (bean.checkSmsType) {
            CheckSmsType.REGISTER_USER -> {
                type = ImageCodeType.REGISTER_USER
            }
            CheckSmsType.FIND_PASSWORD_CHECKMOBILE -> {
                type = ImageCodeType.FIND_PASSWORD
            }
            CheckSmsType.FIND_PASSWORD -> {
                type = ImageCodeType.FIND_PASSWORD
            }
            CheckSmsType.REGISTER_USER_OR_BIND_PHONE -> {
                type = ImageCodeType.LOGIN
            }
            CheckSmsType.DYNAMIC_LOGIN -> {
                type = ImageCodeType.LOGIN
            }
            CheckSmsType.EDIT_PASSWORD -> {
                if (bean.editPasswordValidateMobile) {
                    type = ImageCodeType.VALIDATE_MOBILE
                } else {
                    type = ImageCodeType.EDIT_PASSWORD
                }
            }
            CheckSmsType.UPDATE_PHONE_CHECKMOBILE -> {
                type = ImageCodeType.VALIDATE_MOBILE
            }
            CheckSmsType.UPDATE_PHONE -> {
                type = ImageCodeType.BIND_PHONE
            }
        }

        loadImageCode(type)
    }

    fun loadImageCode(type: ImageCodeType) {

        val observable = baseApi.loadVcode(scene = type.codeParams).map { BitmapFactory.decodeStream(it.byteStream()) }
        baseSubscribe(observable, Consumer { result ->
            loadImageCodeLiveData.value = result
//            imageLoader?.invoke(result)
//            providerView().loadImageCodeResult(result)
        })
    }

    val sendSmsLiveData = MutableLiveData<CheckSmsBean>()
    val checkSmsCodeLiveData = MutableLiveData<CheckSmsBean>()

    /**
     * @Note   发送短信
     */
    fun sendSms(bean: CheckSmsBean, activity: SimpleActivity<*, *>? = null) {
        if (false) {
            return
        }
        var observable: Observable<ResponseBody>? = null
        when (bean.checkSmsType) {
            //发送手机号快捷登录并绑定信息
            CheckSmsType.REGISTER_USER_OR_BIND_PHONE -> {
                observable = passportApi.sendMessageLoginAndBind(mobile = bean.mobile, captcha = bean.imageCode, gr = bean.areaCode)
            }
            //发送手机号快捷登录信息
            CheckSmsType.DYNAMIC_LOGIN -> {
                observable = passportApi.sendMessageLogin(mobile = bean.mobile, captcha = bean.imageCode, gr = bean.areaCode)
            }
            CheckSmsType.EDIT_PASSWORD -> { //修改登录密码不需要手机号,因为用户是登录状态
                observable = passportApi.sendEditMessage(captcha = bean.imageCode)
            }
            //发送注册短信
            CheckSmsType.REGISTER_USER -> {
                observable = passportApi.sendMessageRegister(mobile = bean.mobile, captcha = bean.imageCode, gr = bean.areaCode)
            }
            CheckSmsType.FIND_PASSWORD_CHECKMOBILE -> {//todo 找回密码有点特殊,需要先验证密码后再找回密码
                checkFindPwdAccount(bean)
            }
            //找回密码
            //todo 验证密码只有一次
            CheckSmsType.FIND_PASSWORD -> {
                observable = passportApi.sendMessageFindPassword(captcha = bean.imageCode)
            }
            CheckSmsType.UPDATE_PHONE_CHECKMOBILE -> {
                observable = passportApi.sendEditMessage(captcha = bean.imageCode)
            }
            CheckSmsType.UPDATE_PHONE -> {
                observable = passportApi.sendBindPassword(mobile = bean.mobile, captcha = bean.imageCode, gr = bean.areaCode)
            }
        }
        if (observable == null) {
            return
        }
        baseSubscribe(observable, SimpleNetParams(), Consumer { result ->
//            providerView().sendSmsSuccess(bean)
            sendSmsLiveData.value = bean
        }, Consumer {
            loadImageCode(bean)
            if (it != null && it is CustomThrowable) {
                val customThrowable = it
                if (customThrowable.errResultModel != null) {
                    if (customThrowable.errResultModel?.code == "119") {
                        activity?.finish()
                    }
                }
            }
        })
    }

    /**
     * 校验手机短信
     */
    fun checkSmsCode(bean: CheckSmsBean) {
        var observable: Observable<ResponseBody>? = null
        when (bean.checkSmsType) {
            CheckSmsType.REGISTER_USER_OR_BIND_PHONE -> {
                if (bean.connectInfo != null) {
                    authMobileBind(bean.connectInfo!!.type, bean.connectInfo!!.unionId, bean.mobile, bean.smsCode)
                } else {
                    showMessage("error : no bind info!")
                }
            }
            CheckSmsType.DYNAMIC_LOGIN -> {
                if (bean.connectInfo != null) {
                    authMobileBind(bean.connectInfo!!.type, bean.connectInfo!!.unionId, bean.mobile, bean.smsCode)
                } else {
                    smsLogin(bean.mobile, bean.smsCode)
                }
            }
            CheckSmsType.EDIT_PASSWORD -> {
                //验证修改密码验证码
                observable = memberApi.checkUpdatePwdCode(bean.smsCode)
            }
            CheckSmsType.REGISTER_USER -> {
                //验证注册验证码
                observable = passportApi.checkMobileMessage(mobile = bean.mobile, scene = "REGISTER", smsCode = bean.smsCode, gr = bean.areaCode)
            }
            CheckSmsType.FIND_PASSWORD -> {
                //找回密码验证码
                observable = passportApi.validFindCode(bean.smsCode)
            }
            CheckSmsType.UPDATE_PHONE_CHECKMOBILE -> {
                observable = memberApi.checkExchangeBindCode(bean.smsCode)
            }
            CheckSmsType.UPDATE_PHONE -> {
                observable = memberApi.exchangeBindMobile(bean.mobile, bean.smsCode, gr = bean.areaCode)
            }
        }
        if (observable == null) {
            return
        }
        baseSubscribe(observable, Consumer {
//            providerView().checkSmsCodeSuccess(bean)
            checkSmsCodeLiveData.value = bean
        })
    }

    val smsLoginLiveData = MutableLiveData<Array<Any>>()

    /**
     * @Note   手机登录
     * @param  phone 手机号
     * @param  vcode 验证码
     */
    private fun smsLogin(phone: String, smsCode: String) {
        val observable = passportApi.mobileLogin(phone, smsCode)
                .flatMap {
                    return@flatMap memberApi.memberInfo()
                }
        baseSubscribe(observable, SimpleNetParams(), Consumer { result ->
            UserRepository.setUserInfo(result, true)
//            providerView().smsLoginResult(true)
            smsLoginLiveData.value = arrayOf(true)
        }, Consumer {
//            providerView().smsLoginResult(false)
            smsLoginLiveData.value = arrayOf(false)
        })
    }

    /**
     *用于找回密码中的验证账号
     */
    private fun checkFindPwdAccount(bean: CheckSmsBean) {
        val observable = passportApi.checkFindPwdAccount(bean.mobile, bean.imageCode)
                .map { findPassModel ->
                    val uuid = findPassModel.uuid
                    if (uuid.isNotEmpty()) {
                        UUID.refreshUUID(uuid)
                    }
                    bean.mobile = findPassModel.mobile
                    bean.areaCode = ""
                    return@map findPassModel
                }
        baseSubscribe(observable, SimpleNetParams(), Consumer { findPassModel ->
//            providerView().sendSmsSuccess(bean)
            sendSmsLiveData.value = bean
        }, Consumer { loadImageCode(bean) })
    }

    private fun authMobileBind(type: String, openId: String, phone: String, vcode: String) {
        var login_binder = true//todo false,表示注册并绑定第三方openid,就要去设置密码
        val observable = passportApi.authMobileBind(vcode, openId, type, phone)
                .flatMap {
                    login_binder = it.login_binder
                    return@flatMap memberApi.memberInfo()
                }
        baseSubscribe(observable, Consumer { result ->
            UserRepository.setUserInfo(result, true)
//            providerView().smsLoginResult(true, login_binder)
            smsLoginLiveData.value = arrayOf(true, login_binder)
        })
    }

    val loginSuccessResultLiveData = MutableLiveData<Boolean>()

    /**
     * @Note   普通账号登录
     * @param  username 账号
     * @param  password 密码
     * @param  vcode    验证码
     */
    fun userLogin(username: String, password: String, vcode: String) {
        val observable = passportApi.login(username, MD5Util.MD5Encode(password, null)!!, vcode)
                .flatMap {
                    return@flatMap memberApi.memberInfo()
                }
        baseSubscribe(observable, SimpleNetParams(), Consumer { result ->
            UserRepository.setUserInfo(result, true)
//            providerView().loginSuccessResult()
            loginSuccessResultLiveData.value = true
        }, Consumer {
//            providerView().loadImageCode()
            loginSuccessResultLiveData.value = false
        })
    }


    /**
     * @Note   修改/设置密码
     * @param  password 密码
     * @param  vcode 图片验证码
     */
    fun modifyPassword(password: String, vcode: String) {
        val observable = memberApi.updatePassword(UUID.uuid, vcode, MD5Util.MD5Encode(password, null)!!)
        baseSubscribe(observable, Consumer { result ->
//            providerView().modifyPasswordSuccess()
            modifyPasswordSuccessLiveData.value = true
        })
    }

    val modifyPasswordSuccessLiveData = MutableLiveData<Boolean>()

    /**
     * @Note   注册会员
     * @param  mobile 手机号
     * @param  password 密码
     */
    fun registerUser(password: String, bean: CheckSmsBean) {
        val observable = passportApi.register(mobile = bean.mobile, password = MD5Util.MD5Encode(password, null)!!, gr = bean.areaCode)
                .flatMap { return@flatMap memberApi.memberInfo() }
                .map {
                    return@map it
                }
        baseSubscribe(observable, Consumer { result ->
            UserRepository.setUserInfo(result, true)
//            providerView().modifyPasswordSuccess()
            modifyPasswordSuccessLiveData.value = true
        })
    }

    /**
     * @Note   找回密码
     * @param  password 密码
     * @param  vcode  验证码
     */
    fun findPassword(password: String, vcode: String) {
        val observable = passportApi.findPassword(UUID.uuid, MD5Util.MD5Encode(password, null)!!)
                .map {
                    return@map 1
                }
        baseSubscribe(observable, Consumer { result ->
//            providerView().modifyPasswordSuccess()
            modifyPasswordSuccessLiveData.value = true
        })
    }

    /**
     * 注册并绑定第三方uid
     */
    fun registerConnectUser(password: String, imageCode: String, bean: CheckSmsBean) {
        val observable = passportApi.register(bean.mobile, MD5Util.MD5Encode(password, null)!!, bean.areaCode)
                .flatMap {
                    return@flatMap passportApi.authNormalBind(
                            bean.connectInfo!!.unionId,
                            bean.connectInfo!!.type,
                            bean.mobile,
                            MD5Util.MD5Encode(password, null)!!,
                            imageCode)
                }
                .flatMap { return@flatMap memberApi.memberInfo() }
                .map {
                    return@map it
                }
        baseSubscribe(observable, Consumer { result ->
            UserRepository.setUserInfo(result, true)
//            providerView().modifyPasswordSuccess()
            modifyPasswordSuccessLiveData.value = true
        })
    }

}